home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / T U R B O Language / Turbo C Tools v6.0 / EXAMPLES / CRITERR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  6.8 KB  |  255 lines

  1. /*
  2. *    CRITERR.C    Demonstrate implementation and use of a
  3. *            critical error handler.
  4. *
  5. *  The purpose of CRITERR is to show a working example of
  6. *  implementation and use of a critical error (int 0x24) handler.
  7. *
  8. *  This program displays a prompt on the screen telling the user
  9. *  to open the drive A: door, and then to press ENTER.    The
  10. *  program then attempts to open the file "A:\GARBAGE".  This
  11. *  will generate a critical error (int 0x24), which the program's
  12. *  interrupt handler will respond to, by reporting the error, and
  13. *  setting DOS to do a retry of the failed operation.
  14. *
  15. *  The command line format is as follows:
  16. *
  17. *    criterr
  18. *
  19. *  Version    6.00 (C)Copyright Blaise Computing Inc. 1987, 1989
  20. *
  21. */
  22.  
  23.  
  24.  
  25. #include <dos.h>
  26. #include <stdio.h>
  27.  
  28. #include <bfiles.h>
  29. #include <bintrupt.h>
  30.  
  31.  
  32. #define  CRIT_VEC 0x24
  33. #define  STACKSIZE  3000          /* Items for the critical     */
  34. #define  NUMSTACKS     2          /* error ISR.            */
  35.  
  36. ISRCTRL crit_blk;
  37. char    crit_stk[STACKSIZE*NUMSTACKS];
  38.  
  39. void crit_err(ALLREG *,ISRCTRL *,ISRMSG *);
  40. void write_str(char *);
  41. void wait_key(void);
  42.  
  43. void main()
  44. {
  45.     char resp[2];
  46.     FILE *file;
  47.  
  48.         /* Install DOS critical error handler.            */
  49.     isinstal (CRIT_VEC, crit_err, "TCT CRITER 5.00",
  50.           &crit_blk, crit_stk, STACKSIZE, NUMSTACKS);
  51.  
  52.         /* Display message, wait for ENTER.            */
  53.     flprompt ("Open A: drive door, then press ENTER to test handler: ",
  54.            resp, sizeof (resp));
  55.  
  56.         /* Now try to open (for reading) a file on drive A:.*/
  57.     file = fopen ("a:\\garbage", "r");
  58.  
  59.     if (file != NULL)
  60.     fclose (file);
  61.  
  62.         /* We do not have to re-install the previous        */
  63.         /* INT 0x24 handler because that happens        */
  64.         /* automatically on program termination.        */
  65. }
  66.  
  67.  
  68.  
  69. /**
  70. *
  71. * Name        crit_err -- Handle DOS critical error
  72. *
  73. * Synopsis    (To be called only from ISR dispatcher.)
  74. *
  75. *        crit_err(pregs,pisrblk,pmsg);
  76. *
  77. *        ALLREG *pregs      Pointer to structure containing
  78. *                  register values in effect when
  79. *                  interrupt occurred.
  80. *        ISRCTRL *pisrblk  Pointer to control block for this
  81. *                  ISR.
  82. *        ISRMSG *pmsg      Pointer to structure containing
  83. *                  messages between this ISR and the
  84. *                  dispatcher.
  85. *
  86. * Description    This function analyzes the information provided by DOS
  87. *        in the machine registers, reports the error and the
  88. *        device on which it occurs, and awaits a keystroke.  It
  89. *        returns to DOS in such a way as to request another
  90. *        retry.
  91. *
  92. * Returns    pregs->ax.hl.l      Value 1, thereby requesting a retry.
  93. *
  94. **/
  95.  
  96. void crit_err (pregs, pisrblk, pmsg)
  97. ALLREG    *pregs;
  98. ISRCTRL *pisrblk;
  99. ISRMSG    *pmsg;
  100. {
  101.     DEV_HEADER dh;
  102.     char       report[100];
  103.     int        bad_fat;
  104.  
  105.     static char *message[] =
  106.     {
  107.     "Attempt to write on write-protected diskette", /* 0x00       */
  108.     "Unknown unit",                                 /* 0x01       */
  109.     "Drive not ready",                              /* 0x02       */
  110.     "Unknown command",                              /* 0x03       */
  111.     "Data error (CRC)",                             /* 0x04       */
  112.     "Bad request structure length",                 /* 0x05       */
  113.     "Seek error",                                   /* 0x06       */
  114.     "Unknown media type",                           /* 0x07       */
  115.     "Sector not found",                             /* 0x08       */
  116.     "Printer out of paper",                         /* 0x09       */
  117.     "Write fault",                                  /* 0x0a       */
  118.     "Read fault",                                   /* 0x0b       */
  119.     "General failure",                              /* 0x0c       */
  120.     "Unknown error 13",                             /* 0x0d       */
  121.     "Unknown error 14",                             /* 0x0e       */
  122.     "Invalid disk change"                           /* 0x0f       */
  123.     };
  124.     static char *area[4] =          /* Area on disk in which error  */
  125.     {                      /* may occur.              */
  126.     "DOS area (system files)",
  127.     "file allocation table",
  128.     "directory",
  129.     "data area"
  130.     };
  131.  
  132.         /* Get rid of compiler warning messages.        */
  133.     bad_fat = *((int *) pmsg);
  134.     bad_fat = *((int *) pisrblk);
  135.  
  136.     bad_fat = 0;
  137.  
  138.     if (pregs->ax.hl.h & 0x80)
  139.     {        /* Character device or FAT error.            */
  140.  
  141.         /* Get the device header into local storage.        */
  142.     utpeekn (uttofar (pregs->bp, pregs->si, char), &dh, sizeof (dh));
  143.  
  144.         /* If it is a character device, print its name.     */
  145.     if (dh.attr & 0x8000)
  146.         sprintf (report,
  147.              "\015\012<<Critical error on device \"%-.8s\":>>",
  148.              dh.name);
  149.  
  150.     else    /* It must be a block device FAT error.         */
  151.     {
  152.         bad_fat = 1;
  153.         sprintf (report, "\015\012<<Bad FAT on drive %c:>>",
  154.              pregs->ax.hl.l + 'A');
  155.     }
  156.     }
  157.     else    /* Disk error.                        */
  158.     sprintf(report,
  159.         "\015\012<<Critical error while %s %s on drive %c:>>",
  160.         (pregs->ax.hl.h & 1) ? "writing" : "reading",
  161.         area[(pregs->ax.hl.h & 6) >> 1],
  162.         pregs->ax.hl.l + 'A');
  163.     write_str (report);
  164.     write_str ("\015\012");
  165.     write_str (message[utlobyte(pregs->di)]);
  166.     write_str ("\015\012");
  167.  
  168.     write_str (report);
  169.  
  170.  
  171.     if (bad_fat)
  172.     write_str("\015\012<<BAD FAT -- Turn the computer off!\007\015\012>>");
  173.  
  174.     else
  175.     {
  176.     write_str ("\015\012Correct condition and press any key.\015\012");
  177.     wait_key ();
  178.     pregs->ax.hl.l = 1;          /* Retry.               */
  179.     }
  180. }
  181.  
  182.  
  183.  
  184. /**
  185. *
  186. * Name        write_str -- Write string to DOS console using only DOS
  187. *                 functions 1-12.  Ignore CTRL-BREAK.
  188. *
  189. * Synopsis    write_str(pstring);
  190. *
  191. *        char *pstring      Pointer to beginning of character
  192. *                  array containing message to write.
  193. *                  The string must be terminated by NUL
  194. *                  ('\0') as usual.
  195. *
  196. * Description    This function writes a string to the DOS console using
  197. *        DOS functions 1-12 only.  CTRL-BREAK and CTRL-C are
  198. *        ignored.
  199. *
  200. * Returns    (None.    Function return type is void.)
  201. *
  202. **/
  203.  
  204. void write_str(pstring)
  205. char *pstring;
  206. {
  207.     union REGS regs;
  208.     char  ch;
  209.  
  210.     regs.x.ax = 0x0600;
  211.     while ((ch = *pstring++) != '\0')
  212.     {
  213.     if (ch != (char) 0xff)
  214.     {
  215.         regs.x.dx = utbyword (0, ch);
  216.         int86 (FL_DOS_INT, ®s, ®s);
  217.     }
  218.     }
  219. }
  220.  
  221.  
  222.  
  223. /**
  224. *
  225. * Name        wait_key -- Await keystroke and discard it.
  226. *                (Use DOS functions 1-12 only.)
  227. *
  228. * Synopsis    wait_key();
  229. *
  230. * Description    This function discards any pending keystrokes, waits for
  231. *        one more keystroke, and discards it.  If the new
  232. *        keystroke is CTRL-BREAK or CTRL-C, the program is
  233. *        aborted.
  234. *
  235. * Returns    (None.    Function return type is void.)
  236. *
  237. **/
  238.  
  239. void wait_key()
  240. {
  241.     union REGS regs;
  242.  
  243.     regs.x.ax = 0x0c08;     /* Flush keyboard & await one key.  */
  244.     int86 (FL_DOS_INT, ®s, ®s);
  245.  
  246.         /* If IBM PC extended character, read & discard the */
  247.         /* second byte of the keystroke.            */
  248.     if (utlobyte (regs.x.ax) == 0)
  249.     {
  250.     regs.x.ax = 0x0600;
  251.     regs.x.dx = 0x00ff;
  252.     int86 (FL_DOS_INT, ®s, ®s);
  253.     }
  254. }
  255.